<?php

namespace App\Common\Libs;

use App\Consts\ExceptionCode;
use App\Consts\GlobalMessageConst;
use Illuminate\Support\Facades\Log;
use JPush\Client as JPushModel;


/*
 * 基本概念
 * platform 推送平台设置，目前支持 ios, android, winphone
 * audience 推送设备对象，表示一条推送可以被推送到哪些设备列表。确认推送设备对象，JPush 提供了多种方式，比如：别名、标签、注册 ID、分群、广播等。
 * notification 通知内容体。是被推送到客户端的内容。与 message 一起二者必须有其一，可以二者并存。
 * message 应用内消息。或者称作：自定义消息，透传消息。是被推送到客户端的内容。与 notification 一起二者必须有其一，可以二者并存。
 *
 * */
class JPush
{
    protected static $client = null;

    //推送类型
    const PUSH_TYPE_ALL = 1;
    const PUSH_TYPE_TAG = 2;
    const PUSH_TYPE_ALIAS = 3;
    const PUSH_TYPE_REG_ID = 4;

    private function __construct()
    {
    }

    private function __clone()
    {
    }

    /**
     * 获取实例
     */
    public static function getInstance()
    {
        if (!self::$client) {
            self::$client = new JPushModel(config('jpush.app_key'), config('jpush.master_secret'), null);
        }
        return self::$client;
    }

    /**
     * 给android或ios推送消息
     * JPush 当前支持 Android, iOS, QuickApp，Windows Phone 三个平台的推送。其关键字分别为："android", "ios", "quickapp","winphone"。
     * 推送到所有平台：{ "platform" : "all" }; 指定特定推送平台：{ "platform" : ["android", "ios","quickapp"] }
     * @param array $params
     * @param string $messageTpye 极光推送类型 1通知 2自定义
     */
    public static function pushNotify($params,$messageType = GlobalMessageConst::JPUSH_TYPE_CUSTOM)
    {
        //推送平台
        $platform = $params['platform'] ?? 'all';
        //推送标题
        $title = $params['title'] ?? '';
        //推送内容
        $content = $params['content'] ?? '';
        //通知栏样式ID
        $builder_id = $params['builder_id'] ?? 0;
        //附加字段
        $extras = $params['extras'] ?? '';
        //推送类型
        $type = $params['type'] ?? '';

        //推送目标(注册ID)
        $reg_id = $params['reg_id'] ?? '';
        //推送目标(标签)
        $tag = $params['tag'] ?? '';
        //推送目标(别名)
        $alias = $params['alias'] ?? '';

        try {
            $push = self::getInstance()->push();

            //设置平台
            $push->setPlatform($platform);

            switch ($type) {
                case self::PUSH_TYPE_ALL:
                    $push->addAllAudience();
                    break;
                case self::PUSH_TYPE_TAG:
                    $push->addTag($tag);
                    break;
                case self::PUSH_TYPE_ALIAS:
                    $push->addAlias($alias);
                    break;
                case self::PUSH_TYPE_REG_ID:
                    $push->addRegistrationId($reg_id);
                    break;
            }


            if ($messageType == GlobalMessageConst::JPUSH_TYPE_NOTICE){
                /* 通知消息
                 * */
                $push->androidNotification($content, [
                    'title' => $title,
                    'builder_id' => $builder_id,
                    'extras' => $extras,
                ])->iosNotification($content, [
                    'sound' => 'sound',
                    'badge' => '+1',
                    'extras' => $extras
                ])->options([
                    'apns_production' => config('jpush.apns_production'),//apns_production 如果目标平台是 iOS，True 表示推送生产环境，False 表示要推送开发环境；
                    //表示离线消息保留时长(秒)
                    'time_to_live' => 86400,
                ]);
            }elseif ($messageType == GlobalMessageConst::JPUSH_TYPE_CUSTOM){
                /*
                 * 自定义消息
                 * */
                $push->message($content, [
                    'title' => $title,
                    'content_type' => 'text',
                    'extras' => $extras,
                ])->options([
                    'apns_production' => config('jpush.apns_production'),//apns_production 如果目标平台是 iOS，True 表示推送生产环境，False 表示要推送开发环境；
                    //表示离线消息保留时长(秒)
                    'time_to_live' => 86400,
                ]);
            }else{
                return false;
            }

            $response = $push->send();

            if ($response['http_code'] != 200) {
                Log::channel('jpush')->error(json_encode($response, JSON_UNESCAPED_UNICODE));
            }

//            return $response;
            return ExceptionCode::OPERATING_SUCCESS;
        } catch (\Throwable $e) {
            Log::channel('jpush')->error(json_encode([
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'message' => $e->getMessage(),
                'params' => $params,
            ], JSON_UNESCAPED_UNICODE));
            return ExceptionCode::CODE_FAIL;
        }
    }

    /**
     * 获取指定设备的别名和标签
     */
    public static function getDevices($reg_id)
    {
        $response = self::getInstance()->device()->getDevices($reg_id);
        if ($response['http_code'] == 200) {
            return $response['body'];
        }

        return [];
    }

    /**
     * 给指定设备添加标签
     */
    public static function addTags($reg_id, $tags = [])
    {
        $response = self::getInstance()->device()->addTags($reg_id, $tags);

        if ($response['http_code'] == 200) {
            return true;
        }

        return false;
    }

    /**
     * 清空指定设备的标签
     */
    public static function clearTags($reg_id)
    {
        $response = self::getInstance()->device()->clearTags($reg_id);

        if ($response['http_code'] == 200) {
            return true;
        }

        return false;
    }

    /**
     * 清空指定设备的标签
     */
    public static function removeTags($reg_id, $tags = [])
    {
        $response = self::getInstance()->device()->removeTags($reg_id, $tags);

        if ($response['http_code'] == 200) {
            return true;
        }

        return false;
    }

    /**
     * 更新指定设备的别名
     */
    public static function updateAlias($reg_id, $alias)
    {
        $response = self::getInstance()->device()->updateAlias($reg_id, $alias);

        if ($response['http_code'] == 200) {
            return true;
        }

        return false;
    }
}

